package com.lvy.hczn.front.business.controller;

import com.lvy.hczn.front.common.annotation.Log;
import com.lvy.hczn.front.common.core.controller.BaseController;
import com.lvy.hczn.front.common.core.domain.AjaxResult;
import com.lvy.hczn.front.common.core.page.TableDataInfo;
import com.lvy.hczn.front.common.core.redis.RedisCache;
import com.lvy.hczn.front.common.enums.BusinessType;
import com.lvy.hczn.front.common.utils.poi.ExcelUtil;
import com.lvy.hczn.front.system.domain.business.GoodsBox;
import com.lvy.hczn.front.business.dto.Param;
import com.lvy.hczn.front.business.service.GoodsBoxDetailService;
import com.lvy.hczn.front.business.service.GoodsBoxService;
import com.lvy.hczn.front.business.util.ResultUtil;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.service.WarehouseService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@Controller
@RequestMapping("/wcs/box/")
@Slf4j
public class GoodsBoxController extends BaseController {

    @Autowired
    private GoodsBoxService goodsBoxService;

    @Autowired
    private GoodsBoxDetailService goodsBoxDetailService;

    @Autowired
    private WarehouseService warehouseService;

    private String prefix = "system/box";

    /**
     * 导出货箱信息列表
     */
    @RequiresPermissions("system:box:export")
    @Log(title = "货箱信息", businessType = BusinessType.EXPORT)
    @PostMapping("export")
    @ResponseBody
    public AjaxResult export(GoodsBox goodsBox) {
        List<GoodsBox> list = goodsBoxService.selectBoxlist(goodsBox);
        ExcelUtil<GoodsBox> util = new ExcelUtil<GoodsBox>(GoodsBox.class);
        return util.exportExcel(list, "货箱信息数据");
    }

    /**
     * 新增货箱信息
     */
    @GetMapping("add")
    public String add() {
        return prefix + "/add";
    }

    /**
     * 新增保存货箱信息
     */
    @RequiresPermissions("system:box:add")
    @Log(title = "货箱信息", businessType = BusinessType.INSERT)
    @PostMapping("add")
    @ResponseBody
    public AjaxResult addSave(GoodsBox goodsBox) {
        return toAjax(goodsBoxService.insertGoodsBox(goodsBox));
    }

    /**
     * 修改货箱信息
     */
    @RequiresPermissions("system:box:edit")
    @GetMapping("edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap) {
        GoodsBox goodsBox = goodsBoxService.getById(id);
        mmap.put("goodsBox", goodsBox);
        return prefix + "/edit";
    }

    /**
     * 修改保存货箱信息
     */
    @RequiresPermissions("system:box:edit")
    @Log(title = "货箱信息", businessType = BusinessType.UPDATE)
    @PostMapping("edit")
    @ResponseBody
    public AjaxResult editSave(GoodsBox goodsBox) {
        return toAjax(goodsBoxService.updateGoodsBox(goodsBox));
    }

    /**
     * 删除货箱信息
     */
    @RequiresPermissions("system:box:remove")
    @Log(title = "货箱信息", businessType = BusinessType.DELETE)
    @PostMapping("remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        return toAjax(goodsBoxService.deleteGoodsBoxByIds(ids));
    }

    @GetMapping("index")
    public String index(ModelMap mmap) {
        mmap.put("warehouse", warehouseService.selectLocalWarehouseFront());
        return prefix + "/box";
    }

    /**
     * 查询货箱信息列表
     *
     * @param goodsBox
     * @return
     */
    @RequiresPermissions("system:box:list")
    @PostMapping("list")
    @ResponseBody
    public TableDataInfo list(GoodsBox goodsBox) {
        startPage();
        List<GoodsBox> list = goodsBoxService.selectBoxlist(goodsBox);
        return getDataTable(list);
    }

    /**
     * 调拨配送校验货箱
     * <p>
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "调拨配送校验货箱", notes = "调拨配送校验货箱")
    @PostMapping("sortByBoxCode")
    @ResponseBody
    public ResultUtil sortByBoxCode(@Valid @RequestBody Param param) {
        try {
            GoodsBox goodsBox = goodsBoxService.sortByBoxCode(param);
            return ResultUtil.ok(goodsBox);
        } catch (Exception e) {
            log.error("sortByBoxCode:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 根据货箱编号查空箱
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "根据货箱编号查空箱", notes = "根据货箱编号查空箱")
    @PostMapping("selectEmptyBoxByBoxCode")
    @ResponseBody
    public ResultUtil selectEmptyBoxByBoxCode(@RequestBody Param param) {
        try {
            GoodsBox goodsBox = goodsBoxService.selectEmptyBoxByBoxCode(param);
            return ResultUtil.ok(goodsBox);
        } catch (Exception e) {
            log.error("selectEmptyBoxByBoxCode:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "分拣检查货箱是否为空箱(无详情，则为空箱)", notes = "分拣检查货箱是否为空箱(无详情，则为空箱)")
    @PostMapping("checkEmptyGoodsBox")
    @ResponseBody
    public ResultUtil checkEmptyGoodsBox(@RequestBody String boxCode) {
        try {
            GoodsBox goodsBox = goodsBoxService.selectIncDetailByBoxCode(boxCode);
            return ResultUtil.ok(goodsBox);
        } catch (Exception e) {
            log.error("checkEmptyGoodsBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "分拣称重完成，则检查货箱商品重量是否为空箱", notes = "分拣称重完成，则检查货箱商品重量是否为空箱")
    @PostMapping("checkShelfLocation")
    @ResponseBody
    public ResultUtil checkShelfLocation(@RequestBody String boxCode) {
        try {
            goodsBoxService.checkShelfLocation(boxCode);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("checkShelfLocation:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 需要合并的箱子列表，根据批次查询同一批次重量小于等于weight以及合并体积能合并到一个箱子的箱子，展示出来，
     * 多个箱子合并到一个箱子，考虑多个箱子的总重量和总体积能放到同一个箱子里，且考虑多层，则箱子体积变小
     * 同一箱子,箱子体积0.1立方米，一个箱子可包含两层，每层0.04立方米
     * 不考虑同一品类不同供应商的原料合并，减少分拣员拿错的概率
     *
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-04-29 15:20:36
     */
    @ApiOperation(value = "需要合并的箱子列表", notes = "需要合并的箱子列表")
    @PostMapping("selectMergeBox")
    @ResponseBody
    public ResultUtil selectMergeBox(@RequestBody Param param) {
        try {
            GoodsBox goodsBox = new GoodsBox();
            List<Object> list = goodsBoxDetailService.selectMergeBox(goodsBox, param.getUpOrDownPolicy().getClientId(), param.isDownload());
            return ResultUtil.ok(list);
        } catch (Exception e) {
            log.error("selectMergeBox:", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 合并货箱，出库下个货箱
     *
     * @param clientId
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-07-29 15:52:12
     */
    @ApiOperation(value = "合并货箱，出库下个货箱", notes = "合并货箱，出库下个货箱")
    @PostMapping("downloadMergeBox")
    @ResponseBody
    public ResultUtil downloadMergeBox(@RequestBody String clientId) {
        try {
            goodsBoxService.downloadMergeBox(clientId);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("downloadMergeBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 销售退货入库下架货箱
     *
     * @param clientId
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-07-29 15:52:12
     */
    @ApiOperation(value = "销售退货入库下架货箱", notes = "销售退货入库下架货箱")
    @PostMapping("downloadReturnBox")
    @ResponseBody
    public ResultUtil downloadReturnBox(@RequestBody String clientId) {
        try {
            goodsBoxService.downloadReturnBox(clientId);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("downloadReturnBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 临期报损出库下架货箱
     *
     * @param clientId
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-07-29 15:52:12
     */
    @ApiOperation(value = "临期报损出库下架货箱", notes = "临期报损出库下架货箱")
    @PostMapping("downloadFrmLossBox")
    @ResponseBody
    public ResultUtil downloadFrmLossBox(@RequestBody String clientId) {
        try {
            goodsBoxService.downloadFrmLossBox(clientId);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("downloadReturnBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 空箱或指定货箱出库
     *
     * @param param
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-07-29 15:52:12
     */
    @ApiOperation(value = "货箱出库", notes = "空箱或指定货箱出库")
    @PostMapping("downloadEmptyBox")
    @ResponseBody
    public ResultUtil downloadEmptyBox(@RequestBody Param param) {
        try {
            goodsBoxService.downloadEmptyBox(param);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("downloadEmptyBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }
}
